iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
自我挑戰組

跟著 Go 實戰聖經 一起自學 Go系列 第 18

DAY 18 Go 語言 自訂型別 (custom types) 及結構 (struct) 的定義

  • 分享至 

  • xImage
  •  

自訂型別 (custom types)

在 Go 語言中,我們可以使用核心型別作為基礎,來建制自訂型別,且自訂型別擁有本來核心型別的零值,也可以跟同型別的資料做比較,但是自訂型別不能跟本來的核心型別做比較,除非我們有先做型別轉換(後面會教到如何型別轉換)。自訂顧名思義-自己定義,我們可以自己對這個型別加上自訂的函式或方法,這是原始核心型別做不到的。

type <自訂型別名稱> <核心型別>

例:想以字串作為基礎,建立一個名為 myLove 的自訂型別,如下:

type myLove string

範例 1:

package main

import "fmt"

type myLove string // 定義一個自訂型別

func getMyLoves() (myLove, myLove, myLove) {
    var myFirstLove myLove = "奇犽" // 將自訂型別建立變數
    var mySecondLove myLove  // 自訂型別也擁有零值,所以這邊會是空字串
    var myLastLove myLove
    myLastLove = "奇犽"

    return myFirstLove, mySecondLove, myLastLove
}

func main() {
    myFirstLove, mySecondLove, myLastLove := getMyLoves()
    fmt.Println("我的初戀:", myFirstLove, " 我的第二個戀人:", mySecondLove, " 我最後的愛:", myLastLove)  // 印出自訂型別的值
    fmt.Println(myFirstLove == mySecondLove) // 比對自訂型別的值
    fmt.Println(myFirstLove == myLastLove)
}

範例 1(執行結果):

我的初戀: 奇犽  我的第二個戀人:   我最後的愛: 奇犽
false
true

補充:
在 Go 語言中我們經常看到大家用自訂型別來包裝資料,如此一來將型別名稱自訂為你的資料名稱,可以讓程式碼更好理解、閱讀及接手的人可以更好維護。

為型別取別名

上面一個範例我們學習到如何自定一個型別,但是有時候我們並不需要真的建立一個型別,而是只需要給型別一個別名 (alias) ,來讓我們更方便的使用它,如此一來並不會創造新的型別,但你也還是可以使用自己取的別名名稱來使用該型別。

type <別名> = <型別>

例: type id = int 會讓 int 型別多一個 id 的別名,你可以把 id 當成 int 使用,而 id 仍然是 int 的型別沒錯。

結構 (struct)

先前我們學習的陣列、切片、 map 都可以用來把相同型別的資料放在一起,但有時候你的資料內容又會更複雜化,光是數字、字串已經不足以處理你的資料,這時就是結構 (struct) 出場的時機啦!

以昨天的範例來說 myFavorite 裡面有 fruit.animal.dessert.weather 但我喜歡的東西有太多太多了 color,member,month...等,如果你要調查每個人喜歡東西的名單,雖然也可以使用 map ,但這樣你每搜集一個人的資料,就要重複建立一樣的 key ,其實是非常費力的,所以結構這不就來了嗎~~只要把這些資料都收在一個單獨的結構中,我們就可以自由地調整或是控制它。

簡而言之, 結構 (struct) 是一種自訂型別,你可以對結構命名,也可以指定 欄位 (field) 名稱與其的型別。

結構的定義

type <結構型別的名稱> struct {
    <欄位 1> <型別>
    <欄位 2> <型別>
    <欄位 3> <型別>
    ...
    <欄位 N> <型別>
}

欄位是結構的變數,欄位名稱需是獨一無二的,且欄位與型別需寫在大括號之間,但型別就沒有限制,無論是指標、集合、或是其他結構也行。

讀取結構欄位和對欄位賦值:

<結構變數名稱>.<欄位名稱>

如果大家有學習過其他程式語言,或許有聽說過 物件導向程式設計語言 一詞, Go 語言雖然不是物件導向程式設計語言,但是結構卻是一個很接近物件導向程式設計語言 類別 (class) 的東西,但與類別不同的是 結構無法被繼承

雖然 Go 語言不是物件導向語言,但我們還是經常把結構稱為物件,且將其欄位稱為屬性(就連 Go 的官方文件也是這樣稱呼的)。

當定義好結構型別就可以將其用來建立變數,接下來我們使用範例來練習建立變數吧!

範例 2:

package main

import "fmt"

type myFavorite struct {  // 定義一個名為 myFavorite 的結構型別
    name string  // 定義結構裡的欄位名稱與型別
    color string
    isCommon bool
    month int
}

func getFavorites() []myFavorite {
    userA := myFavorite{
        color: "yellow", // 有欄位名稱的賦值(可不用照順序)
        isCommon: true,
        name: "Krystal",
        month: 12,
    }

    userB := myFavorite{
        name: "Andy", // 有欄位名稱的賦值,沒有賦值的欄位會是零值
        month: 8,
    }

    userC := myFavorite{
        "Coco",  // 沒有欄位名稱的賦值(一定要照順序)
        "blue",
        false,
        1,
    }

    var userD myFavorite  // 先定義一個 userD 結構變數
    userD.name = "Tom"  // 使用 結構變數.欄位名稱 來賦值
    userD.color = "gray"
    userD.isCommon = true
    userD.month = 7

    return []myFavorite{userA, userB, userC, userD}
}

func main() {
    favorites := getFavorites()

    for i := 0; i < len(favorites); i++ {
        fmt.Println(i,favorites[i])
    }
}

範例 2(執行結果):

0 {Krystal yellow true 12}
1 {Andy  false 8}
2 {Coco blue false 1}
3 {Tom gray true 7}

今天簡單介紹了在 Go 語言中自訂型別以及結構的定義,那明天我們繼續深入來了解一下,結構還有哪些其他用法,明天見~


上一篇
DAY 17 Go 語言 的複合型別 - 映射表 (map)
下一篇
DAY 19 Go 語言 匿名結構 (anonymous strut) 與比較結構
系列文
跟著 Go 實戰聖經 一起自學 Go30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言